package data;


import java.util.HashMap;
import java.util.LinkedList;
import java.util.TreeMap;

import entities.ScheduleActivity;
import entities.ScheduleDate;
import entities.ScheduleDay;


/**
 * Save/ load between xml and objects
 * 
 * @author Christian
 * 
 */
public class ScheduleParser {

	/**
	 * This method takes raw TimeEdit-html and turns it into an usable list of
	 * activities.
	 *  
	 * @author Mattias
	 * @param rawData
	 *            - The raw TimeEdit HTML code
	 * @return LinkedList<ScheduledActivity> - A well formed list with all
	 *         activities extracted from the raw data.
	 */
	public LinkedList<ScheduleActivity> makeSchedulePretty(
			LinkedList<String> rawData) {
		LinkedList<ScheduleActivity> prettyList = new LinkedList<ScheduleActivity>();
		LinkedList<String> cleanedRawList = rawData;
		//Some of these strings are not used, but since TE provides the information it's best to get it in case we need them for later.
		String tmpWeek, tmpDay, tmpDate, tmpTime, tmpPlace, tmpCourse, tmpEquipment, tmpType, tmpOwner, tmpActivity, tmpNotes;
		int tmpStartTime, tmpEndTime;
		boolean isNewActivity = false;
		boolean isFirstWeek = true;
		int tmpInt;
		
		tmpWeek="Vecka 0, 1970";//In order to prevent "may not be initialized" error
		tmpDay="Tis";//In order to prevent "may not be initialized" error




		// Remove uninteresting data from the beginning of the given code
		while (!cleanedRawList.getFirst().contains("<TABLE class='booking' border='0' cellpadding='5' cellspacing='0'>")) {
			cleanedRawList.removeFirst();
		}

		// Remove uninteresting data from the end of the given code
		while (!cleanedRawList.getLast().equals("<table border='0' cellpadding='0' cellspacing='0'>")) {
			cleanedRawList.removeLast();
		}
		cleanedRawList.removeFirst();

		/*
		 * Main program loop, gets all activities! Extremely ugly due to the ugly TimeEdit HTML-code :-/
		 */
		while(!cleanedRawList.isEmpty())
		{
			if (cleanedRawList.getFirst().equals("</TR>")){
				cleanedRawList.removeFirst();
			}
			if (cleanedRawList.getFirst().equals("<TR>")){
				cleanedRawList.removeFirst();
			}

			if(cleanedRawList.getFirst().startsWith("<TD style='border-left:1px solid #888888; border-top:1px solid #888888; border-right:1px solid #888888; border-bottom:1px solid #888888;"))
			{
				tmpInt = cleanedRawList.getFirst().indexOf("Vecka");
				tmpWeek = cleanedRawList.getFirst().substring(tmpInt, cleanedRawList.getFirst().indexOf("</font>"));
				cleanedRawList.removeFirst();

				if(isFirstWeek){
					for(int a=0;a<11;a++){ //Remove junk after first week-data
						cleanedRawList.removeFirst();
					}
					isFirstWeek=false;
				}else{
					for(int a=0;a<4;a++){ //Remove junk after week-data
						cleanedRawList.removeFirst();
					}
				}
				tmpDay = cleanedRawList.getFirst().substring(109, 112); // form: WdWdWd (i.e Tor)
				cleanedRawList.removeFirst();
				tmpDate = cleanedRawList.getFirst().substring(109, 115); // form: DD MMM or D MMM	   
				cleanedRawList.removeFirst();
				tmpTime = cleanedRawList.getFirst().substring(141, 156); // form: HH:mm&#45;HH:mm
				cleanedRawList.removeFirst();
				isNewActivity=true;
				/********GET ACTIVITY********/
				// Get course
				tmpInt = cleanedRawList.getFirst().indexOf('<',99);
				tmpCourse = cleanedRawList.getFirst().substring(99, tmpInt);
				cleanedRawList.removeFirst();

				// Get place
				tmpInt = cleanedRawList.getFirst().indexOf('<', 99);
				tmpPlace = cleanedRawList.getFirst().substring(99, tmpInt);
				cleanedRawList.removeFirst();

				// Get type
				tmpInt = cleanedRawList.getFirst().indexOf('<',99);
				tmpType = cleanedRawList.getFirst().substring(99, tmpInt);
				cleanedRawList.removeFirst();

				// Get owner
				tmpInt = cleanedRawList.getFirst().indexOf('<', 99);
				tmpOwner = cleanedRawList.getFirst().substring(99, tmpInt);
				cleanedRawList.removeFirst();

				// Get equipment
				tmpInt = cleanedRawList.getFirst().indexOf('<',99);
				tmpEquipment = cleanedRawList.getFirst().substring(99, tmpInt);
				cleanedRawList.removeFirst();

				// Get activity
				tmpInt = cleanedRawList.getFirst().indexOf('<',99);
				tmpActivity = cleanedRawList.getFirst().substring(99, tmpInt);
				cleanedRawList.removeFirst();

				// Get notes
				tmpInt = cleanedRawList.getFirst().indexOf('<',99);
				tmpNotes = cleanedRawList.getFirst().substring(99, tmpInt);
				cleanedRawList.removeFirst();

				//Make tmpTime into proper integers
				tmpStartTime=Integer.parseInt((String)tmpTime.subSequence(0, 2));
				tmpStartTime*=100;
				tmpStartTime+=Integer.parseInt((String)tmpTime.subSequence(3, 5));

				tmpEndTime=Integer.parseInt((String)tmpTime.subSequence(10, 12));
				tmpEndTime*=100;
				tmpEndTime+=Integer.parseInt((String)tmpTime.subSequence(13, 15));
				

				prettyList.add(new ScheduleActivity(tmpPlace, "", tmpType, tmpCourse, tmpStartTime, tmpEndTime, tmpDate.replace('<', ' ').trim(),tmpDay,tmpWeek, 1, 0));

				for(int a=0;a<4;a++){ //Remove junk after activity-data
					if(cleanedRawList.getFirst().contains("Vecka"))
						break;
					cleanedRawList.removeFirst();
				}
				


			}
			if(isNewActivity){
				if(cleanedRawList.getFirst().equals("<TD style='border-left:1px solid #888888; border-bottom:1px solid #888888; ' nowrap>&nbsp;</TD>")){
					return prettyList;
				}
				if(cleanedRawList.getFirst().contains("&nbsp") && cleanedRawList.getFirst().contains("t_timehead")){
					cleanedRawList.removeFirst();
					cleanedRawList.removeFirst();

					/********GET ACTIVITY********/

					//Get time
					tmpTime = cleanedRawList.getFirst().substring(141, 156); // form: HH:mm&#45;HH:mm
					cleanedRawList.removeFirst();

					//Make tmpTime into proper integers
					tmpStartTime=Integer.parseInt((String)tmpTime.subSequence(0, 2));
					tmpStartTime*=100;
					tmpStartTime+=Integer.parseInt((String)tmpTime.subSequence(3, 5));

					tmpEndTime=Integer.parseInt((String)tmpTime.subSequence(10, 12));
					tmpEndTime*=100;
					tmpEndTime+=Integer.parseInt((String)tmpTime.subSequence(13, 15));

					// Get course
					tmpInt = cleanedRawList.getFirst().indexOf('<',99);
					tmpCourse = cleanedRawList.getFirst().substring(99, tmpInt);
					cleanedRawList.removeFirst();

					// Get place
					tmpInt = cleanedRawList.getFirst().indexOf('<', 99);
					tmpPlace = cleanedRawList.getFirst().substring(99, tmpInt);
					cleanedRawList.removeFirst();

					// Get type
					tmpInt = cleanedRawList.getFirst().indexOf('<',99);
					tmpType = cleanedRawList.getFirst().substring(99, tmpInt);
					cleanedRawList.removeFirst();

					// Get owner
					tmpInt = cleanedRawList.getFirst().indexOf('<', 99);
					tmpOwner = cleanedRawList.getFirst().substring(99, tmpInt);
					cleanedRawList.removeFirst();

					// Get equipment
					tmpInt = cleanedRawList.getFirst().indexOf('<',99);
					tmpEquipment = cleanedRawList.getFirst().substring(99, tmpInt);
					cleanedRawList.removeFirst();

					// Get activity
					tmpInt = cleanedRawList.getFirst().indexOf('<',99);
					tmpActivity = cleanedRawList.getFirst().substring(99, tmpInt);
					cleanedRawList.removeFirst();

					// Get notes
					tmpInt = cleanedRawList.getFirst().indexOf('<',99);
					tmpNotes = cleanedRawList.getFirst().substring(99, tmpInt);
					cleanedRawList.removeFirst();

					prettyList.add(new ScheduleActivity(tmpPlace, "", tmpType, tmpCourse, tmpStartTime, tmpEndTime, prettyList.getLast().getDate(),tmpDay,tmpWeek, 1, 0));
					
					for(int a=0;a<4;a++){ //Remove junk after activity-data
						if(cleanedRawList.getFirst().contains("Vecka"))
							break;
						cleanedRawList.removeFirst();
					}


				}else if(cleanedRawList.getFirst().equals("<TR>")){
					cleanedRawList.removeFirst();
					if(cleanedRawList.getFirst().contains("Vecka")){
						isNewActivity=false;
						continue;
					}
				}else if(cleanedRawList.getFirst().contains("t_timehead") && !cleanedRawList.getFirst().contains("&nbsp")){
					tmpDay = cleanedRawList.getFirst().substring(109, 112); // form: WdWdWd (i.e Tor)
					cleanedRawList.removeFirst();
					tmpDate = cleanedRawList.getFirst().substring(109, 115); // form: DD MMM or D MMM
					cleanedRawList.removeFirst();
					tmpTime = cleanedRawList.getFirst().substring(141, 156); // form: HH:mm&#45;HH:mm
					cleanedRawList.removeFirst();
					
					/********GET ACTIVITY********/
					// Get course
					tmpInt = cleanedRawList.getFirst().indexOf('<',99);
					tmpCourse = cleanedRawList.getFirst().substring(99, tmpInt);
					cleanedRawList.removeFirst();

					// Get place
					tmpInt = cleanedRawList.getFirst().indexOf('<', 99);
					tmpPlace = cleanedRawList.getFirst().substring(99, tmpInt);
					cleanedRawList.removeFirst();

					// Get type
					tmpInt = cleanedRawList.getFirst().indexOf('<',99);
					tmpType = cleanedRawList.getFirst().substring(99, tmpInt);
					cleanedRawList.removeFirst();

					// Get owner
					tmpInt = cleanedRawList.getFirst().indexOf('<', 99);
					tmpOwner = cleanedRawList.getFirst().substring(99, tmpInt);
					cleanedRawList.removeFirst();

					// Get equipment
					tmpInt = cleanedRawList.getFirst().indexOf('<',99);
					tmpEquipment = cleanedRawList.getFirst().substring(99, tmpInt);
					cleanedRawList.removeFirst();

					// Get activity
					tmpInt = cleanedRawList.getFirst().indexOf('<',99);
					tmpActivity = cleanedRawList.getFirst().substring(99, tmpInt);
					cleanedRawList.removeFirst();

					// Get notes
					tmpInt = cleanedRawList.getFirst().indexOf('<',99);
					tmpNotes = cleanedRawList.getFirst().substring(99, tmpInt);
					cleanedRawList.removeFirst();

					//Make tmpTime into proper integers
					tmpStartTime=Integer.parseInt((String)tmpTime.subSequence(0, 2));
					tmpStartTime*=100;
					tmpStartTime+=Integer.parseInt((String)tmpTime.subSequence(3, 5));

					tmpEndTime=Integer.parseInt((String)tmpTime.subSequence(10, 12));
					tmpEndTime*=100;
					tmpEndTime+=Integer.parseInt((String)tmpTime.subSequence(13, 15));

					prettyList.add(new ScheduleActivity(tmpPlace, "", tmpType, tmpCourse, tmpStartTime, tmpEndTime, tmpDate.replace('<', ' ').trim(),tmpDay,tmpWeek, 1, 0));

					for(int a=0;a<4;a++){ //Remove junk after activity-data
						if(cleanedRawList.getFirst().contains("Vecka"))
							break;
						cleanedRawList.removeFirst();
					}
				}
			}
		}
		return prettyList;
	}
	
	/**
	 * Method that returns a map with lists of activities separated into different days
	 * 
	 * @Author Simon
	 * @param unorderedList - list of lists to be ordered
	 * @return TreeMap<ScheduleDate, ScheduleDay> - Sorted map of days mapped to dates
	 */
	public TreeMap<ScheduleDate, ScheduleDay> makeDateMapMultiple(LinkedList<LinkedList<ScheduleActivity>> unorderedList) {
		TreeMap<ScheduleDate, ScheduleDay> returnMap = new TreeMap<ScheduleDate, ScheduleDay>();
		ScheduleDate schedDate;
		ScheduleDay dayActivities;
		for(LinkedList<ScheduleActivity> currentList : unorderedList){
			for(ScheduleActivity sa : currentList){
				schedDate = new ScheduleDate(sa.getWeekAndYear(),sa.getDate(),sa.getWeekDay());
				dayActivities = returnMap.get(schedDate);
				if(dayActivities == null){
					dayActivities = new ScheduleDay();
					dayActivities.addActivity(sa);
					returnMap.put(schedDate, dayActivities);
				} else {
					dayActivities.addActivity(sa);
					returnMap.put(schedDate, dayActivities);
				}
			}
			
		}
	
	
	
		return returnMap;
	}
	
	
	/**
	 * Method that returns a map with lists of activities separated into different days
	 * 
	 * @Author Simon
	 * @param unorderedList - list to be ordered
	 * @return TreeMap<ScheduleDate, ScheduleDay> - Sorted map of lists of activities mapped to dates
	 */
	public TreeMap<ScheduleDate, ScheduleDay> makeDateMapSingle(LinkedList<ScheduleActivity> unorderedList) {
		TreeMap<ScheduleDate, ScheduleDay> returnMap = new TreeMap<ScheduleDate, ScheduleDay>();
		ScheduleDate schedDate;
		ScheduleDay dayActivities;

		for(ScheduleActivity sa : unorderedList){
			schedDate = new ScheduleDate(sa.getWeekAndYear(),sa.getDate(),sa.getWeekDay());
			dayActivities = returnMap.get(schedDate);
			if(dayActivities == null){
				dayActivities = new ScheduleDay();
				dayActivities.addActivity(sa);
				returnMap.put(schedDate, dayActivities);
			} else {
				dayActivities.addActivity(sa);
				returnMap.put(schedDate, dayActivities);
			}
		}
			
		
	
	
	
		return returnMap;
	}
	
	
	
	/**
	 * This method takes raw TimeEdit-html and turns it into an usable map of
	 * codes that TE uses for the courses.
	 * 
	 * @author Simon
	 * @param rawData
	 *            - The raw TimeEdit HTML code
	 * @return HashMap<ScheduledActivity> - A well formed list with all
	 *         activities extracted from the raw data.
	 */
	public HashMap<String, Integer> makeSearchPretty(LinkedList<String> rawData) {

		HashMap<String, Integer> prettyMap = new HashMap<String, Integer>();
		LinkedList<String> cleanedRawList = rawData;
		int tmpInt;

		// Remove uninteresting data from the beginning of the given code
		while (!cleanedRawList
				.getFirst()
				.startsWith("<TD><a href='javascript:addObject(")) {
			cleanedRawList.removeFirst();
		}

		// Remove uninteresting data from the end of the given code
		while (!cleanedRawList.getLast().equals(
				"</FORM>")) {
			cleanedRawList.removeLast();
		}

		// Extract the all important data!
		while (!cleanedRawList.isEmpty()) {

			if (cleanedRawList.getFirst().equals("</TR>")) {
				cleanedRawList.removeFirst();
			}

			if (cleanedRawList.getFirst().startsWith(
					"<TD><a href='javascript:addObject(")) {
				String tmpSplit[] = cleanedRawList.getFirst().split("\\(");
				tmpSplit = tmpSplit[1].split("\\)");
				tmpInt = Integer.parseInt(tmpSplit[0]);
				cleanedRawList.removeFirst();
				cleanedRawList.removeFirst();
				tmpSplit = cleanedRawList.getFirst().split("\\>");
				tmpSplit = tmpSplit[1].split("\\<");
				prettyMap.put(tmpSplit[0], tmpInt);
			} else {
				cleanedRawList.removeFirst(); // If it gets here then it found nothing of use...
			}

		}
		
		return prettyMap;

	}

	private void xmlToObject() {

	}

	private void pushSave() {

	}

	private void retrieveSave() {

	}
}
